from ..hardware.tec_controller import *
from ..hardware.pump_controller import PumpController
import time
import threading
from ..utils.config import SYSTEM_STATE_FILE
from ..utils.simple_logging import get_app_logger

# 获取日志记录器
logger = get_app_logger("snail")


class Snail:
    def __init__(self):
        self.tec = TecController(port='/dev/ttySC1', baudrate=57600)
        self.pump = PumpController(port='/dev/ttySC0', baudrate=9600)
        self.monitor_event = threading.Event()  # 用于控制温度监控线程
        # 定义试剂管道
        self.reagent = {
            "chamber": 1,
            "air": 2,
            "reagent03": 3,
            "reagent04": 4,
            "reagent05": 5,
            "reagent06": 6,
            "reagent07": 7,
            "reagent08": 8,
            "reagent09": 9,
        }
        # 连接试剂的管道
        self.reagent2 = {
            "reagent03": 3,
            "reagent04": 4,
            "reagent05": 5,
            "reagent06": 6,
            "reagent07": 7,
            "reagent08": 8,
            "reagent09": 9,
        }
        # 试剂充满管道所需液体的体积（45微升）
        self.tubevol = 2150
        # 出液口的管道体积
        self.tubevol2 = 3700

    def wash(self):
        """1.初始化机器,2.使用清水清洗3遍管道并将管道充满试剂,3.最终排空"""
        self.pump.set_speed(speed=1000)
        self.pump.move_to_chamber_and_dispense_to_zero()
        # 清洗2遍所有管道
        for i in range(2):
            for key, value in self.reagent2.items():
                if self.pump.query_pump_position() >= 8000:
                    self.pump.move_to_chamber_and_dispense_to_zero()
                current_reagent = value
                self.pump.move_and_aspirate(volume=self.tubevol + 500, port_number=current_reagent)

        self.pump.move_to_chamber_and_dispense_to_zero()
        self.pump.modify_json_file(file_path=SYSTEM_STATE_FILE,key="device_status", new_value="idle")
        # 排空管道内液体

    def empty_tube(self):
        """将管道试剂抽出，最终排空到废液"""
        self.pump.set_speed(speed=800)
        self.pump.move_pump_to_zero()
        for key, value in self.reagent2.items():
            target_port = value
            # 旋转到目标端口并抽液
            self.pump.move_and_aspirate(volume=self.tubevol + 1000, port_number=target_port)
            self.pump.move_to_chamber_and_dispense_to_zero()
        self.pump.move_and_aspirate(volume=self.tubevol2 + 1000, port_number=2)  # 抽取空气
        self.pump.move_to_chamber_and_dispense_to_zero()  # 将空气吹入chamber
        self.pump.modify_json_file(file_path=SYSTEM_STATE_FILE,key="device_status", new_value="idle")

    def fill_tube(self,reagent2=None):
        self.pump.set_speed(speed=500)
        if reagent2 is None:
            reagent2 = self.reagent2
        """充满reagent2中的管道"""
        for key, value in reagent2.items():
            self.pump.move_to_chamber_and_dispense_to_zero()
            target_port = value
            self.pump.move_and_aspirate(volume=self.tubevol, port_number=target_port)
        self.pump.move_to_chamber_and_dispense_to_zero()
        self.pump.move_and_aspirate(volume=self.tubevol2 + 1000, port_number=2)
        self.pump.move_to_chamber_and_dispense_to_zero()
        self.pump.modify_json_file(file_path=SYSTEM_STATE_FILE,key="device_status", new_value="idle")


    def inject(self, reagent, times=1, volume=100, temperature=25, timewait=60, 
            stop_event=None, system_state=None):
        """
        修改后的注入函数，支持在每个关键操作前后检查暂停
        """
        volume = volume * 10
        
        try:
            # 设置初始速度
            if stop_event and stop_event.is_set():
                return
            self.pump.set_speed(speed=150)
            
            for i in range(times):
                # 检查暂停和停止 - 在每次循环开始前
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                
                # 1. 从试剂端口抽液
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_and_aspirate(volume=volume, port_number=reagent)
                
                # 2. 将液体注入反应腔
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_and_dispense(volume=volume, port_number=self.reagent["chamber"])
                
                # 3. 设置高速并从空气端口抽气
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.set_speed(speed=600)
                
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_and_aspirate(volume=self.tubevol2 - 380, port_number=self.reagent["air"])
                
                # 4. 设置低速并排空到零位
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.set_speed(speed=150)
                
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_to_chamber_and_dispense_to_zero()
                
                # 5. 等待时间（支持暂停）
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                
                start_time = time.time()
                while (time.time() - start_time) < timewait:
                    if stop_event and stop_event.is_set():
                        return
                    if system_state and system_state.reaction_paused:
                        while system_state and system_state.reaction_paused:
                            time.sleep(0.5)
                            if stop_event and stop_event.is_set():
                                return
                    time.sleep(1)  # 分段等待，每秒检查一次
                
                # 6. 排出液体 - 设置高速
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.set_speed(speed=600)
                
                # 7. 从空气端口大量抽气
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_and_aspirate(volume=self.tubevol2 + 1000, port_number=self.reagent["air"])
                
                # 8. 设置低速并排空到零位
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.set_speed(speed=150)
                
                if stop_event and stop_event.is_set():
                    return
                if system_state and system_state.reaction_paused:
                    while system_state and system_state.reaction_paused:
                        time.sleep(0.5)
                        if stop_event and stop_event.is_set():
                            return
                self.pump.move_to_chamber_and_dispense_to_zero()
        
        except Exception as e:
            logging.error(f"注入操作出错: {e}")
            if system_state:
                system_state.device_status = 'error'
                system_state.save_state()
            raise


    def monitor_temperature(self, interval=5):
        """
        监控温度并记录到日志
        :param interval: 温度读取间隔时间（秒）
        """
        while not self.monitor_event.is_set():
            temperature = self.tec.get_temperature()  # 获取当前温度
            logger.info(f"当前温度: {temperature}°C")
            time.sleep(interval)

    def start_temperature_monitoring(self, interval=5):
        """
        启动温度监控线程
        :param interval: 温度读取间隔时间（秒）
        """
        self.monitor_event.clear()  # 重置事件
        self.monitor_thread = threading.Thread(
            target=self.monitor_temperature, args=(interval,)
        )
        self.monitor_thread.start()
        logger.info("温度监控已启动")

    def stop_temperature_monitoring(self):
        """
        停止温度监控线程
        """
        self.monitor_event.set()  # 设置事件，通知线程退出
        self.monitor_thread.join()  # 等待线程结束
        logger.info("温度监控已停止")

